
class EventEmitter {

    /**  @type { {[key:string]:Function[]} } */
    #_listeners

    /**
     * 事件监听器注册方法
     * @param {string} type 事件类型
     * @param {Function} listener 监听函数
     * @param {boolean} prependListener default false , 插入事件队列的方式
     */
    on(type, listener, prependListener = false) {
        if (this.#_listeners === undefined) this.#_listeners = Object.create(null)

        const listeners = this.#_listeners

        if (listeners[type] === undefined) {
            listeners[type] = []
        }

        if (listeners[type].indexOf(listener) !== -1) {
            if (prependListener === true) {
                listeners[type].unshift(listener)
            } else {
                listeners[type].push(listener)
            }
        }

    }

    /**
     * 事件监听器注册方法
     * @param {string} type 事件类型
     * @param {Function} listener 监听函数
     * @param {boolean} prependListener default false , 插入事件队列的方式
     */
    addEventListener(type, listener, prependListener) {
        this.on(type, listener, prependListener)
    }

    /**
     * @param {string} type 事件类型
     * @param {Function} listener 监听函数
     * @returns {boolean}
     */
    hasEventListener(type, listener) {

        if (this.#_listeners === undefined) return false

        const listeners = this.#_listeners

        return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1

    }

    /**
     * @param {string} type 
     * @param { Function } listener 
     * @param { boolean }  prependListener 
     */
    once(type, listener, prependListener = false) {
        // 先绑定，调用后删除
        function wrap() {
            listener(...arguments);
            this.removeListener(type, wrap);
        }
        this.on(type, wrap, prependListener);
    }

    eventNames() {

    }

    removeListener(type, listener) {
        if (this.#_listeners === undefined) return

        const listenerArray = this.#_listeners[type]

        if (listenerArray !== undefined) {
            const index = listenerArray.indexOf(listener)

            if (index !== -1) {
                listenerArray.splice(index, 1)
            }
        }
    }

    removeAllListener() {
        Reflect.ownKeys(this.#_listeners).forEach(type => {
            this.#_listeners[type].length = 0
        })
    }

    /**
     * 返回当前事件类型的所有事件
     * @param {string} type 
     */
    listeners(type) {
        if (this.#_listeners !== undefined) {
            return this.listeners[type]
        }
    }

    /**
     * 触发事件
     * @param {string} type 
     */
    emit(type) {
        if (this.#_listeners !== undefined) {
            const listeners = this.#_listeners[type]
            if (listeners !== undefined) {
                listeners.forEach(listener => listener())
            }
        }
    }

}

